<?php
require_once 'common.php';
require_once 'OaCompanyModel.php';
require_once 'OaAppModel.php';
require_once OA_LIB_PATH . '/inner/service/SDOServiceDeposit.php';
require_once OA_LIB_PATH . '/inner/service/SDOServicePayment.php';

/**
 * 开发者模型
 * @author wangjiajun
 *
 */
class OaDeveloperModel extends OpModel
{    
    // 证件类型
    const CERTIFICATE_TYPE_ID_CARD = 1;        // 身份证
    
    private $_oaWebDb;
    private $_companyTable;
    private $_developerTable;
    private $_companyDeveloperTable;
    private $_appDeveloperTable;
    private $_appTestAccount;
    private $_userMigrationTable;
    
    public static function getConstantValueByName($name, $default = 0)
    {
        return self::_getConstByName($name, '', $default, 'OaDeveloperModel');
    }
    
    public function __construct($logger = null)
    {
        if (is_null($logger)) {
            $logger = getOaModelLogger();
        }
        parent::__construct($logger);
        $dbConfig = Oa_Util_Config::getSingleDbConfig(OA_WEB_DB_CLUSTER_ID);
        $db = OpDbModel::getInstance($dbConfig, $logger);
        $this->_oaWebDb = $db;
        $this->_companyTable = new OpTableModel($db, 'company', $logger);
        $this->_developerTable = new OpTableModel($db, 'developer', $logger);
        $this->_companyDeveloperTable = new OpTableModel($db, 'company_developer', $logger);
        $this->_appDeveloperTable = new OpTableModel($db, 'app_developer', $logger);
        $this->_appTestAccount = new OpTableModel($db, 'app_test_account', $logger);
        $this->_userMigrationTable = new OpTableModel($db, 'user_migration', $logger);
    }
    
    /**
     * 新增一个开发者
     * @param int $developerId
     * @param string $pt
     * @param string $name
     * @param array $row
     * @return boolean
     */
    public function createDeveloper($developerId, $pt, $name, $row = array())
    {
        $row = array_merge(array(
            'uid' => $developerId,
            'pt' => $pt,
            'name' => $name
        ), $row);
        if (!isset($row['create_time'])) {
            $row['create_time'] = date('Y-m-d H:i:s');
        }
        if (isset($row['cert_no']) && !isset($row['cert_type'])) {
            $row['cert_type'] = self::CERTIFICATE_TYPE_ID_CARD;
        }
        return $this->_developerTable->insert($row, null, false);
    }
    
    /**
     * 查询某个开发者
     * @param int $developerId
     * @param array $columns
     * @return array|null|boolean
     */
    public function getDeveloper($developerId, $columns = null)
    {
        return $this->_developerTable->getRow(array('uid' => $developerId), null, $columns);
    }
    
    /**
     * 查询多个开发者，返回数组以开发者ID为Index
     * @param array $developerIds
     * @return array|boolean
     */
    public function getDeveloperMulti($developerIds)
    {
        if (empty($developerIds)) {
            return array();
        }
        foreach ($developerIds as &$developerId) {
            $developerId = (int) $developerId;
        }
        unset($developerId);
        $sql = "SELECT * FROM developer WHERE uid IN (" . implode(',', $developerIds) . ")";
        $rows = $this->_developerTable->query($sql);
        if ($rows === false) {
            return false;
        }
        $developers = array();
        foreach ($rows as $row) {
            $developers[$row['uid']] = $row;
        }
        return $developers;
    }
    
    /**
     * 查询某个开发者（根据盛大通行证）
     * @param int $developerId
     * @param array $columns
     * @return array|null|boolean
     */
    public function getDeveloperByPt($pt, $columns = null)
    {
        return $this->_developerTable->getRow(array('pt' => $pt), null, $columns);
    }
    
    /**
     * 查询多个开发者（根据盛大通行证），返回数组以pt为Index
     * @param array $pts
     * @return array|boolean
     */
    public function getDeveloperByPtMulti($pts)
    {
        if (empty($pts)) {
            return array();
        }
        foreach ($pts as &$pt) {
            $pt = escapeInput($pt);
        }
        unset($pt);
        $sql = "SELECT * FROM developer WHERE pt IN (" . implode(',', $pts) . ")";
        $rows = $this->_developerTable->query($sql);
        if ($rows === false) {
            return false;
        }
        $developers = array();
        foreach ($rows as $row) {
            $developers[$row['pt']] = $row;
        }
        return $developers;
    }
    
    /**
     * 查询老的用户ID，如果不存在则返回-1
     * @param int $developerId
     * @return int|boolean
     */
    public function getOldUserId($developerId)
    {
        $row = $this->_userMigrationTable->getRow(array(
            'uid' => $developerId
        ));
        if ($row === false) {
            $this->_logger->log("get row failed");
            return false;
        }
        if (is_array($row)) {
            return $row['user_id'];
        } else {
            return -1;
        }
    }
    
    /**
     * 根据指定条件查询开发者列表
     * @param array $where
     * @param int $offset
     * @param int $count
     * @param string $sort
     * @param array $otherWhere
     * @return array|boolean
     */
    public function getDeveloperList($where = null, $offset = 0, $count = null, 
        $sort = null, $otherWhere = null)
    {
        return $this->_developerTable->get($where, $offset, $count, $sort, $otherWhere);
    }
    
    /**
     * 根据指定条件查询开发者总数
     * @param array $where
     * @param array $otherWhere
     * @return int|boolean
     */
    public function getDeveloperListCount($where = null, $otherWhere = null)
    {
        $sql = "SELECT COUNT(*) FROM developer" . getSqlCond($where, null, null, null, $otherWhere);
        $row = $this->_developerTable->query($sql, PDO::FETCH_NUM);
        if ($row === false) {
            $this->_logger->log("query failed");
            return false;
        }
        return (int) $row[0][0];
    }
    
    /**
     * 修改某个开发者的信息
     * @param int $developerId
     * @param array $row
     * @return boolean
     */
    public function modifyDeveloper($developerId, $row)
    {
        return $this->_developerTable->update(array('uid' => $developerId), $row);
    }
    
    /**
     * 根据角色查询所属公司
     * @param int $developerId
     * @param int $role 在公司中的角色，null表示任意角色
     * @param int $offset
     * @param int $count
     * @return array|boolean
     */
    public function getMyCompanys($developerId, $role = null, $offset = 0, $count = null)
    {
        $developerId = (int) $developerId;
        $sql = "SELECT t1.*, t2.name FROM company_developer AS t1 JOIN company AS t2 
        	ON (t1.company_id=t2.id) WHERE developer_id=$developerId";
        if (!is_null($role)) {
            $role = (int) $role;
            $sql .= " AND role=$role";
        }
        $sql .= " ORDER BY id";
        if (!is_null($count)) {
            $offset = (int) $offset;
            $count = (int) $count;
            $sql .= " LIMIT $offset,$count";
        }
        return $this->_oaWebDb->query($sql);
    }
    
    /**
     * 查询所属公司
     * @param int $developerId
     * @param int $offset
     * @param int $count null返回全部
     * @return array|boolean
     */
    public function getBelongToCompanys($developerId, $offset = 0, $count = null)
    {
        return $this->getMyCompanys($developerId, null, $offset, $count);
    }
    
    /**
     * 查询创建的公司
     * @param int $developerId
     * @param int $offset
     * @param int $count null返回全部
     * @return array|boolean
     */
    public function getCreatedCompanys($developerId, $offset = 0, $count = null)
    {
        $where = getSqlCond(array(
        	'creator' => $developerId
        ));
        if (!is_null($count)) {
            $offset = (int) $offset;
            $count = (int) $count;
            $limit = "LIMIT $offset,$count";
        } else {
            $limit = '';
        }
        $sql = "SELECT * FROM company $where ORDER BY create_time $limit";
        return $this->_companyTable->query($sql);
    }
    
    /**
     * 根据角色查询所参与的应用
     * @param int $developerId
     * @param int $role 在应用中的角色，null表示任意角色
     * @param int $offset
     * @param int $count
     * @param boolean $includeDelete 是否包含删除状态的应用
     * @return array|boolean
     */
    public function getMyApps($developerId, $role = null, $offset = 0, $count = null, $includeDelete = false)
    {
        $where = array(
        	'developer_id' => $developerId
        );
        if (!is_null($role)) {
            $where['role'] = $role;
        }
        if ($includeDelete) {
            $otherWhere = array();
        } else {
            $otherWhere = array(
                array(
                	'key' => 'status', 
                	'operation' => '!=', 
                	'value' => OaAppModel::APP_STATUS_DELETE
                )
            );
        }
        $sql = "SELECT app_developer.*, app.name, app.company_id FROM app_developer LEFT JOIN app ON (app_developer.app_id=app.id)" . 
            getSqlCond($where, $offset, $count, 'id ASC', $otherWhere);
        return $this->_oaWebDb->query($sql);
    }
    
    /**
     * 增加测试帐号
     * @param string $pt
     * @param int $creator 添加者，默认为0，表示加入公司时自动成为测试帐号
     * @return boolean 如果已添加过，设置错误号1
     */
    public function addTestAccount($pt, $creator = 0)
    {
        if (is_array($this->getTestAccount($pt))) {
            $this->_setError(1, "already exists");
            return false;
        }
        // 给测试帐号充值
        $message = '';
        if (!SDOServiceDeposit::NewDepositCard($message, $pt, 10000000)) {
            $this->_logger->log($message);
            return false;
        }
        return $this->_appTestAccount->insert(array(
            'pt' => $pt,
            'creator' => $creator,
            'create_time' => date('Y-m-d H:i:s')
        ), null, false);
    }
    
    /**
     * 查询测试帐号
     * @param string $pt
     * @return array|null|boolean
     */
    public function getTestAccount($pt)
    {
        return $this->_appTestAccount->getRow(array(
            'pt' => $pt
        ));
    }
    
    /**
     * 删除测试帐号
     * @param string $pt
     * @return boolean
     */
    public function deleteTestAccount($pt)
    {
        return $this->_appTestAccount->delete(array(
            'pt' => $pt
        ));
    }
    
    /**
     * 查询我添加的测试帐号，包括自己的帐号
     * @param int $developerId
     * @param int $offset
     * @param int $count
     * @return array|boolean
     */
    public function getMyAddedTestAccounts($developerId, $offset = 0, $count = null)
    {
        $rows = $this->_appTestAccount->get(array(
            'creator' => $developerId
        ), $offset, $count, 'create_time ASC');
        if ($rows === false) {
            $this->_logger->log("get failed");
            return false;
        }
        if ($offset == 0) {
            $developer = $this->getDeveloper($developerId);
            $rows = array_merge($this->_appTestAccount->get(array(
                'pt' => $developer['pt']
            )), $rows);
        }
        foreach ($rows as &$row) {
            $message = '';
            $balance = SDOServicePayment::accountAuthen($message, $row['pt']);
            if ($balance === false) {
                $this->_logger->log($message);
                return false;
            }
            $row['balance'] = $balance;
        }
        unset($row);
        return $rows;
    }
}
